/*
 * @Descripttion:
 * @Author: voanit
 * @Date: 2022-05-28 08:58:40
 * @LastEditors: voanit
 * @LastEditTime: 2022-05-28 14:58:02
 */
/* 
字面量+联合
// 字面量
let  name:'jack'='jack'
// 联合
let name2:string='jack'|'tom'

*/

export {}

/* 枚举-基本使用 */
enum Direction {
  'up' = 'up',
  'down' = 'down',
  'left' = 'left',
  'right' = 'right',
}

function fx(direction: Direction) {
  console.log(direction)
}
fx(Direction.up)

/* 枚举类型的应用场景 */

enum Gender {
  'girl',
  'boy',
}
type User = {
  id: number
  name: string
  gender: Gender
}
let user: User = {
  id: 1,
  name: 'jack',
  gender: Gender.boy,
}

/* any */
let n1 = 'jack'
// n1 = 222

const f2 = () => {}
let n2

/* 类型断言 */
// const box = document.getElementById('img') as HTMLImageElement
// console.log(box.src) // ts报错
// type User2 = {
//   name: string
//   age: number
// }

// const u1 = {} as User2

// console.log(u1.age) // 这里就会有提示

// list:[]==list.id

/* typeof */
const res = { name: '小花', city: '武汉', skills: ['js', 'css'] }
type Res = typeof res

function f3(obj: Res) {}

f3(res)

console.log(typeof res) //

/* keyof */
type Obj3 = {
  id: number
  name: string
}

type Obj4 = keyof Obj3
let ids: Obj4 = 'id'

type Point = { x: number; y: number }
type P = keyof Point

let qq: P = 'y'

type T = keyof { a: 1; b: 2 }
let aa: T = 'a'

/* 泛型 */
function fn5<T>(n1: T): T {
  return n1
}

fn5<number>(10)
fn5<string>('10')
fn5('10')
fn5<number[]>([1, 2, 3])
fn5<(number | string)[]>([1, 2, 3, 'a'])
fn5<Array<number>>([1, 2, 3])

function useState2<T>(value: T): [T, (value: T) => T] {
  // return [count, setCount]
  const setVale = (value: T) => value
  return [value, setVale]
}
useState2<number[]>([])

// =====
function fn6<T, S>(n1: T, n2: S): T {
  return n1
}
fn6<number, string>(1, '2')
//泛型-泛型约束

// function fn7<T>(n1: T[]): T[] {
//   console.log(n1.length)

//   return n1
// }

// fn7([1])

interface ILength {
  length: number
}
function fn8<T extends ILength>(n1: T): T {
  console.log(n1.length)

  return n1
}

fn8('111')

/* 泛型-典型应用 */
interface Object {
  id: number
  name: string
}

function fn9<T, Key extends keyof T>(obj: T, key: Key) {}

const person: Object = {
  id: 1,
  name: 'jack',
}
fn9(person, 'name')

const strs = ['a', 'b', 'c']
// 鼠标放在 forEach 上查看类型
strs.forEach
// 泛型接口
interface Iobj<T, S> {
  id: T
  name: S
}

const obj5: Iobj<number, string> = {
  id: 1,
  name: 'jack',
}

const obj6: Iobj<string, string> = {
  id: '1',
  name: 'jack',
}

// 泛型工具类型
/* Partial */
type Props = {
  id: number
  name: string
  arr: string[]
}
type NewProps = Partial<Props>
// type NewProps = {
//   id?: number
//   name?: string
//   arr?: string[]
// }
let obj: NewProps = {
  id: 1,
}
obj = {
  id: 2,
}

/* Readonly */
type NewProps2 = Readonly<Props>
let obj2: NewProps2 = {
  id: 1,
  name: 'jack',
  arr: ['1'],
}
// obj2.id = 2
/* Pick */
type NewProps3 = Pick<Props, 'id' | 'arr'>
const obj3: NewProps3 = {
  id: 1,
  arr: ['22'],
}
